// TODO: CODE REVIEW & CLEANUP!
//
// MusicSearchScreen.xaml.cs
//

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Xml;
using HomeUX.ClientAppSupport;
using HomeUX.ClientControlSupport;
using HomeUX.Controls;
using HomeUX.Synchronization;
using HomeUX.Utilities;

namespace HomeUX.MusicClientLibrary
{

public partial class MusicSearchScreen : UserControl
{
    MusicClientHelper _musicClientHelper;

    TouchButton[] _artistButtons;
    TouchButton[] _albumButtons;
    TouchButton[] _trackButtons;

    int _pendingMusicServerRequests;

    /// <summary>
    /// A <n>String.Format</n>-style format string to use for <n>HeaderTextBlock</n>.  Initialized
    /// from the design-time text value of  <n>HeaderTextBlock</n>.
    /// </summary>
    string _headerFormatString;

    public MusicSearchScreen()
    {
        InitializeComponent();

        // initialize <_headerFormatString>
        _headerFormatString = HeaderTextBlock.Text;

        Loaded += MusicSearchScreen_Loaded;

        _artistButtons = new TouchButton[]
        {
            ArtistButton1, ArtistButton2, ArtistButton3
        };

        _albumButtons = new TouchButton[]
        {
            AlbumButton1, AlbumButton2
        };

        _trackButtons = new TouchButton[]
        {
            TrackButton1, TrackButton2, TrackButton3
        };

        foreach (TouchButton button in _artistButtons)
            button.Visibility = Visibility.Collapsed;

        foreach (TouchButton button in _albumButtons)
            button.Visibility = Visibility.Collapsed;

        foreach (TouchButton button in _trackButtons)
            button.Visibility = Visibility.Collapsed;

        SeeAllArtistsButton.Visibility = Visibility.Collapsed;
        SeeAllAlbumsButton.Visibility = Visibility.Collapsed;
        SeeAllTracksButton.Visibility = Visibility.Collapsed;
    }

    void MusicSearchScreen_Loaded(object sender, RoutedEventArgs e)
    {
        _musicClientHelper = new MusicClientHelper(this, BeginLoadingDataFromMusicServer,
            OnParcelReceived);

        HeaderTextBlock.Text = String.Format(_headerFormatString, _musicClientHelper.MusicDeviceName);

        _musicClientHelper.TryToLoadData();
    }

    void BeginLoadingDataFromMusicServer()
    {
        //Dispatcher.BeginInvoke(delegate
        //{
        //    _musicClientHelper.OnDataLoaded();
        //});
        if (_pendingMusicServerRequests++ == 0)
            SearchTextBox.IsWaiting = true;
        NotFoundTextBlock.Visibility = Visibility.Collapsed;
        string command = ParsedSyncNodeCommand.Format("Search",
             "RecipientId", XmlConvert.ToString(_musicClientHelper.RecipientId),
             "Find", SearchTextBox.Text.Trim(),
             "MaxArtists", XmlConvert.ToString(_artistButtons.Length),
             "MaxAlbums", XmlConvert.ToString(_albumButtons.Length),
             "MaxTracks", XmlConvert.ToString(_trackButtons.Length));
        _musicClientHelper.MusicDeviceNode.ExecuteCommand(command);
    }

    void OnParcelReceived(Guid recipientId, XmlReader reader)
    {
        try
        {
            int artistButtonIndex = 0, albumButtonIndex = 0, trackButtonIndex = 0;
            foreach (XmlElementInfo element in XmlElementInfo.EnumerateElements(reader))
            {
                string artistName, albumId, albumName, trackName;
                switch (element.Name)
                {

                case "DoneSearch":

                    // only update UI on the last of multiple successive searches
                    if (_pendingMusicServerRequests > 1)
                        break;

                    int foundArtistCount = element.GetRequiredIntAttribute("FoundArtistCount");
                    int foundAlbumCount = element.GetRequiredIntAttribute("FoundAlbumCount");
                    int foundTrackCount = element.GetRequiredIntAttribute("FoundTrackCount");

                    if (foundArtistCount > 1)
                    {
                        SeeAllArtistsButton.Text = String.Format("See all {0} artists",
                            foundArtistCount);
                        SeeAllArtistsButton.Visibility = Visibility.Visible;
                    }
                    else
                        SeeAllArtistsButton.Visibility = Visibility.Collapsed;

                    if (foundAlbumCount > 1)
                    {
                        SeeAllAlbumsButton.Text = String.Format("See all {0} albums",
                            foundAlbumCount);
                        SeeAllAlbumsButton.Visibility = Visibility.Visible;
                    }
                    else
                        SeeAllAlbumsButton.Visibility = Visibility.Collapsed;

                    if (foundTrackCount > 1)
                    {
                        SeeAllTracksButton.Text = String.Format("See all {0} tracks",
                            foundTrackCount);
                        SeeAllTracksButton.Visibility = Visibility.Visible;
                    }
                    else
                        SeeAllTracksButton.Visibility = Visibility.Collapsed;

					artistButtonIndex = 0;
					albumButtonIndex = 0;
					trackButtonIndex = 0;

                    SearchTextBox.Focus();
                    break;

                case "FoundArtist":

                    // only update UI on the last of multiple successive searches
                    if (_pendingMusicServerRequests > 1)
                        break;

                    artistName = element.GetRequiredAttribute("ArtistName");
					if (artistButtonIndex < _artistButtons.Length)
					{
						TouchButton button = _artistButtons[artistButtonIndex++];
						button.Tag = artistName;
						button.Text = artistName;
						button.Visibility = Visibility.Visible;
					}
                    break;

                case "FoundAlbum":

                    // only update UI on the last of multiple successive searches
                    if (_pendingMusicServerRequests > 1)
                        break;

                    albumId = element.GetRequiredAttribute("AlbumId");
                    artistName = element.GetRequiredAttribute("ArtistName");
                    albumName = element.GetRequiredAttribute("AlbumName");
					if (albumButtonIndex < _albumButtons.Length)
					{
						TouchButton button = _albumButtons[albumButtonIndex++];
						button.Tag = albumId;
						button.Text = String.Format("{0} - {1}", albumName, artistName);
						button.Visibility = Visibility.Visible;
					}
                    break;

                case "FoundTrack":

                    // only update UI on the last of multiple successive searches
                    if (_pendingMusicServerRequests > 1)
                        break;

                    albumId = element.GetRequiredAttribute("AlbumId");
                    int trackNumber = element.GetRequiredIntAttribute("TrackNumber");
                    artistName = element.GetRequiredAttribute("ArtistName");
                    albumName = element.GetRequiredAttribute("AlbumName");
                    trackName = element.GetRequiredAttribute("TrackName");
					if (trackButtonIndex < _trackButtons.Length)
					{
						TouchButton button = _trackButtons[trackButtonIndex++];
                        button.Tag = new MusicQueueScreen.TrackId()
                        {
                            AlbumId = albumId,
                            TrackNumber = trackNumber
                        };
						button.Text = String.Format("{0} - {1} - {2}", trackName, albumName,
							artistName);;
						button.Visibility = Visibility.Visible;
					}
                    break;

                case "/DoneSearch":

                    //_isLoading = false;
                    //UpdateModalMessage();
                    //LoadingTextBlock.Visibility = Visibility.Collapsed;

                    // only update UI on the last of multiple successive searches
                    if (--_pendingMusicServerRequests == 0)
                    {
                        SearchTextBox.IsWaiting = false;

                        FoundArtistsLabel.Visibility = ClientUtil.GetVisibility(artistButtonIndex > 0);
                        FoundAlbumsLabel.Visibility = ClientUtil.GetVisibility(albumButtonIndex > 0);
                        FoundTracksLabel.Visibility = ClientUtil.GetVisibility(trackButtonIndex > 0);

                        _artistButtons[0].IsLit = (artistButtonIndex == 1);
                        SeeAllArtistsButton.IsLit = (artistButtonIndex > 1);

                        _albumButtons[0].IsLit = (albumButtonIndex == 1);
                        SeeAllAlbumsButton.IsLit = (albumButtonIndex > 1);

                        _trackButtons[0].IsLit = (trackButtonIndex == 1);
                        SeeAllTracksButton.IsLit = (trackButtonIndex > 1);

                        string find = SearchTextBox.Text.Trim();
                        bool showNothingFound = (artistButtonIndex == 0) && (albumButtonIndex == 0) &&
                            (trackButtonIndex == 0) & (find.Length > 0);
                        NotFoundTextBlock.Visibility = ClientUtil.GetVisibility(showNothingFound);
                        if (showNothingFound)
                            NotFoundTextBlock.Text = String.Format("\"{0}\" not found", find);

                        while (artistButtonIndex < _artistButtons.Length)
                            _artistButtons[artistButtonIndex++].Visibility = Visibility.Collapsed;
                        while (albumButtonIndex < _albumButtons.Length)
                            _albumButtons[albumButtonIndex++].Visibility = Visibility.Collapsed;
                        while (trackButtonIndex < _trackButtons.Length)
                            _trackButtons[trackButtonIndex++].Visibility = Visibility.Collapsed;

                        _musicClientHelper.OnDataLoaded();
                    }

                    break;

                }
            }
        }
        catch (InvalidOperationException ex)
        {
            ClientGlobals.Alert(AlertType.Warning,
                "Invalid reply from server: {0}", ex.Message);
        }
    }

    private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        BeginLoadingDataFromMusicServer();
    }

    private void StartOverButton_Click(object sender, RoutedEventArgs e)
    {
        SearchTextBox.Text = String.Empty;
    }

    private void SeeAllArtistsButton_Click(object sender, RoutedEventArgs e)
    {
        Screen screen;
        MusicFoundArtistsScreen screenControl;
        _musicClientHelper.FindMusicScreen("Found Artists", out screen, out screenControl);
        screenControl.Find = SearchTextBox.Text;
        screen.GoTo();
    }

    private void SeeAllAlbumsButton_Click(object sender, RoutedEventArgs e)
    {
        Screen screen;
        MusicFoundAlbumsScreen screenControl;
        _musicClientHelper.FindMusicScreen("Found Albums", out screen, out screenControl);
        screenControl.Find = SearchTextBox.Text;
        screen.GoTo();
    }

    private void SeeAllTracksButton_Click(object sender, RoutedEventArgs e)
    {
        Screen screen;
        MusicFoundTracksScreen screenControl;
        _musicClientHelper.FindMusicScreen("Found Tracks", out screen, out screenControl);
        screenControl.Find = SearchTextBox.Text;
        screen.GoTo();
    }

    private void ArtistButton_Click(object sender, RoutedEventArgs e)
    {
        TouchButton button = _artistButtons.First(b => b == sender);

        Screen screen;
        MusicArtistScreen screenControl;
        _musicClientHelper.FindMusicScreen("Artist", out screen, out screenControl);
        screenControl.ArtistName = (string)button.Tag;
        screen.GoTo();
    }

    private void AlbumButton_Click(object sender, RoutedEventArgs e)
    {
        TouchButton button = _albumButtons.First(b => b == sender);

        Screen screen;
        MusicAlbumScreen screenControl;
        _musicClientHelper.FindMusicScreen("Album", out screen, out screenControl);
        screenControl.AlbumId = (string)button.Tag;
        screenControl.HighlightTrackNumber = -1;
        screen.GoTo();
    }

    private void TrackButton_Click(object sender, RoutedEventArgs e)
    {
        TouchButton button = _trackButtons.First(b => b == sender);
        var trackId = (MusicQueueScreen.TrackId)button.Tag;
        Screen screen;
        MusicAlbumScreen screenControl;
        _musicClientHelper.FindMusicScreen("Album", out screen, out screenControl);
        screenControl.AlbumId = trackId.AlbumId;
        screenControl.HighlightTrackNumber = trackId.TrackNumber;
        screen.GoTo();
    }
}

}
